﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
using BitcoinMarket.DataConnectors;
using Redwerb.BizArk.Core.DateExt;
using System.Collections.ObjectModel;
using BitcoinMarket.ViewModels;
using BitcoinMarket.DataSources;
using Telerik.Windows.Controls;
using System.Globalization;
using Microsoft.Phone.Shell;
using BitcoinMarket.Resources;
using BitcoinMarket.Libs;
using Newtonsoft.Json.Linq;
using System.ComponentModel;
using System.Threading;

namespace BitcoinMarket
{
    public partial class CurrencyDetailPage : PhoneApplicationPage
    {
        public CurrencyDetailPage()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Maximal number of items plotted in the chart
        /// </summary>
        private int chartMaxItemCount;

        public bool DataLoaded = false;
        public int selectedIndex = 0;

        /// <summary>
        /// List of all markets to plot in the trades chart
        /// </summary>
        private Collection<string> MarketsList = new Collection<string>();

        /// <summary>
        /// List of colors to use in charts
        /// </summary>
        private Color[] LineColors = {Colors.Green, Colors.Orange, Colors.Magenta, Colors.Blue, Colors.Purple, Colors.Red, Colors.Cyan, Colors.Gray, Colors.Yellow };

        private string pageURL = "";
        private string pageTitle = "";

        /// <summary>
        /// When page is navigated to set data context to selected item in list
        /// </summary>
        /// <param name="e"></param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            this.chartMaxItemCount = 300;

            
        }

        /// <summary>
        /// Fills the "Current" page with data
        /// </summary>
        private void setCurrentData()
        {
            string Index = "";
            if (NavigationContext.QueryString.TryGetValue("selectedItem", out Index))
            {
                this.selectedIndex = int.Parse(Index);
                BitcoinChartsMarketsCurrencyCollection CurrencyCollection;

                if (App.ViewModel.MarketsDataCollection != null)
                {
                    CurrencyCollection = App.ViewModel.MarketsDataCollection[this.selectedIndex];
                    this.setViewModel(CurrencyCollection);
                }
                else
                {
                    SystemTray.ProgressIndicator = new ProgressIndicator();

                    SystemTray.ProgressIndicator.IsIndeterminate = true;
                    SystemTray.ProgressIndicator.Text = AppResources.LoadingChartData;
                    SystemTray.ProgressIndicator.IsVisible = true;
                  
                    this.DataLoaded = false;

                    BackgroundWorker worker = new BackgroundWorker();
                    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
                    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
                    worker.RunWorkerAsync();

                    //((ApplicationBarMenuItem)ApplicationBar.MenuItems[0]).IsEnabled = false;
                } 
            }
        }

        public void setViewModel(BitcoinChartsMarketsCurrencyCollection CurrencyCollection)
        {
            this.MarketsList.Clear();

            CurrencyDetailViewModel vm = new CurrencyDetailViewModel();

            vm.CurrencyName = CurrencyCollection.Currency;
            System.DateTime unixTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

            Collection<BitcoinChartsMarketsDataItem> newItems = CurrencyCollection.DataItems;
            newItems = new Collection<BitcoinChartsMarketsDataItem>(newItems.OrderByDescending(x => x.LatestTrade).ThenBy(x => x.Volume).ToList());

            foreach (BitcoinChartsMarketsDataItem item in newItems)
            {
                CurrencyItemViewModel ivm = new CurrencyItemViewModel();

                DateTime lTradeDate = unixTime.AddSeconds(Convert.ToInt32(item.LatestTrade)).ToLocalTime();

                ivm.ItemTitle = item.Symbol.ToString();
                ivm.ItemBid = item.Bid.ToString();
                ivm.ItemHigh = item.High.ToString();
                ivm.ItemLTrade = DateExt.ToRelativeTimeString(lTradeDate);
                ivm.ItemVolume = item.Volume < 0 ? "---" : Math.Round(item.Volume, 3).ToString();
                ivm.ItemCurrencyVolume = item.CurrencyVolume.ToString();
                ivm.ItemAsk = item.Ask.ToString();
                ivm.ItemLow = item.Low.ToString();
                ivm.ItemOpen = item.Open < 0 ? "---" : Math.Round(item.Open, 3).ToString();
                ivm.ItemClose = item.Close < 0 ? "---" : Math.Round(item.Close, 3).ToString();
                ivm.ItemAvg = item.Avg < 0 ? "---" : Math.Round(item.Avg, 3).ToString();

                vm.Items.Add(ivm);
                this.MarketsList.Add(ivm.ItemTitle);
            }

            DataContext = vm;

            this.pageURL = "/CurrencyDetailPage.xaml?selectedItem=" + this.selectedIndex + "&currency=" + CurrencyCollection.Currency;
            this.pageTitle = CurrencyCollection.Currency;
        }

        public void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.DataLoaded = true;

            if (App.ViewModel.MarketsDataCollection != null)
            {
                BitcoinChartsMarketsCurrencyCollection CurrencyCollection = App.ViewModel.MarketsDataCollection[this.selectedIndex];

                if (CurrencyCollection != null)
                {
                    this.setViewModel(CurrencyCollection);
                }
                else
                {
                    MessageBox.Show(AppResources.chartDataDownloadError);
                    foreach (var Btn in ApplicationBar.Buttons)
                    {
                        ((ApplicationBarIconButton)Btn).IsEnabled = false;
                    }
                }


                SystemTray.ProgressIndicator.IsVisible = false;
            }
        }

        public void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            App.ViewModel.LoadMarketsData();

            while (App.ViewModel.IsLoading)
            {
                Thread.Sleep(400);
            }
        }

        /// <summary>
        /// Fills the "Trade history" page with data
        /// </summary>
        private void setTradeHistoryData()
        {
            TradesChartProgressBar.Visibility = Visibility.Visible;
            
            //BitcoinChartsMarketsDataConnector TradesConnector = new BitcoinChartsMarketsDataConnector();
            //TradesConnector.GetTradesData(this.MarketsList, this.TradesDataConnectorReady);


            // Get the currency name
            string Index = "";

            if (NavigationContext.QueryString.TryGetValue("currency", out Index))
            { // Check if the currency name is not in the URL
                new QuandlDataConnector(Index, this.QuandlDataConnectorReady);
            }
            else if (NavigationContext.QueryString.TryGetValue("selectedItem", out Index))
            { // If not, get it from somewhere else
                this.selectedIndex = int.Parse(Index);
                BitcoinChartsMarketsCurrencyCollection CurrencyCollection;

                if (App.ViewModel.MarketsDataCollection != null)
                {
                    CurrencyCollection = App.ViewModel.MarketsDataCollection[selectedIndex];
                    new QuandlDataConnector(CurrencyCollection.Currency, this.QuandlDataConnectorReady);
                }
            }
        }

        /// <summary>
        /// Callback for the markets data connector
        /// </summary>
        /// <param name="data"></param>
        private void QuandlDataConnectorReady(Collection<QuandlMarketData> data)
        {
            int n, i = 0;
            ObservableCollection<MarketSelectorItem> markets = new ObservableCollection<MarketSelectorItem>();


            foreach (QuandlMarketData mData in data)
            {
                List<TradesHistoryData> tmpData = new List<TradesHistoryData>();

                n = 0;

                foreach (QuandlDataItem values in mData.Data)
                {
                    System.DateTime dtDateTime = DateTime.Parse(values.Date);

                    tmpData.Add(new TradesHistoryData() { Date = dtDateTime, Value = Double.Parse(values.Weighted_price) });

                    if (n++ > this.chartMaxItemCount)
                    {
                        break;
                    }
                }

                //Create new series for the market
                LineSeries lineSeries = new LineSeries();

                //Set data
                lineSeries.Stroke = new SolidColorBrush(this.LineColors[i % this.LineColors.Count()]);
                lineSeries.ItemsSource = tmpData;
                lineSeries.Name = mData.Name;
                lineSeries.CategoryBinding = new PropertyNameDataPointBinding() { PropertyName = "Date" };
                lineSeries.ValueBinding = new PropertyNameDataPointBinding() { PropertyName = "Value" };
                lineSeries.StrokeThickness = 3;

                markets.Add(new MarketSelectorItem(this.LineColors[i % this.LineColors.Count()], mData.Name, i));

                //Bind the new series to the chart
                TradesChart.Series.Add(lineSeries);

                i++;
            }

            //Fix the date labels
            ((DateTimeContinuousAxis)TradesChart.HorizontalAxis).LabelFormat = CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern;// +" " + CultureInfo.CurrentUICulture.DateTimeFormat.ShortTimePattern;

            this.marketsPicker.ItemsSource = markets;
            foreach (MarketSelectorItem m in markets)
            {
                this.marketsPicker.SelectedItems.Add(m);
            }

            TradesChartProgressBar.Visibility = Visibility.Collapsed;
        }


        /// <summary>
        /// [DEPRECATED] Callback for the bitcoincharts data
        /// </summary>
        /// <param name="data"></param>
        private void TradesDataConnectorReady(Collection<TradesData> data)
        {
            int n, i=0;
            ObservableCollection<MarketSelectorItem> markets = new ObservableCollection<MarketSelectorItem>();
            

            foreach (TradesData trData in data)
            {
                List<TradesHistoryData> tmpData = new List<TradesHistoryData>();

                n = 0;

                foreach (string[] values in trData.Data)
                {
                    if (values.Count() >= 2)
                    {
                        System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
                        dtDateTime = dtDateTime.AddSeconds(Double.Parse(values[0])).ToLocalTime();

                        tmpData.Add(new TradesHistoryData() { Date = dtDateTime, Value = Double.Parse(values[1]) });

                        if (n++ > this.chartMaxItemCount)
                        {
                            break;
                        }
                    }

                }

                //Create new series for the market
                LineSeries lineSeries = new LineSeries();

                //Set data
                lineSeries.Stroke = new SolidColorBrush(this.LineColors[i % this.LineColors.Count()]);
                lineSeries.ItemsSource = tmpData;
                lineSeries.Name = trData.MarketName;
                lineSeries.CategoryBinding = new PropertyNameDataPointBinding() { PropertyName = "Date" };
                lineSeries.ValueBinding = new PropertyNameDataPointBinding() { PropertyName = "Value" };
                lineSeries.StrokeThickness = 3;

                markets.Add(new MarketSelectorItem(this.LineColors[i % this.LineColors.Count()], trData.MarketName, i));

                //Bind the new series to the chart
                TradesChart.Series.Add(lineSeries);

                i++;
            }

            //Fix the date labels
            ((DateTimeContinuousAxis)TradesChart.HorizontalAxis).LabelFormat = CultureInfo.CurrentUICulture.DateTimeFormat.ShortDatePattern;// +" " + CultureInfo.CurrentUICulture.DateTimeFormat.ShortTimePattern;

            this.marketsPicker.ItemsSource = markets;
            foreach (MarketSelectorItem m in markets)
            {
                this.marketsPicker.SelectedItems.Add(m);
            }
            
            TradesChartProgressBar.Visibility = Visibility.Collapsed;
        }

        private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
        {
            // Navigate to the About page
            NavigationService.Navigate(new Uri("/AboutPage.xaml", UriKind.Relative));
        }

        private void ApplicationBarMenuItem_Click_1(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/AppSettingsPage.xaml", UriKind.Relative));
        }

        /// <summary>
        /// Hide unnecessary items on landscape mode
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
        {
            PageOrientation orientation = e.Orientation;

            if ((orientation & PageOrientation.Landscape) == PageOrientation.Landscape)
            {
                PageTitle.Visibility = Visibility.Collapsed;
                TitlePanel2.Visibility = Visibility.Collapsed;

               // TradesHorizontalAxis.ShowLabels = false;
            }
            else if ((orientation & PageOrientation.Portrait) == PageOrientation.Portrait)
            {
                PageTitle.Visibility = Visibility.Visible;
                TitlePanel2.Visibility = Visibility.Visible;

                //TradesHorizontalAxis.ShowLabels = true;
            }
        }

        /// <summary>
        /// Event fired after the markets selectbox content has beed changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void marketsPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int count = ((RadListPicker)sender).Items.Count;

            //Hide all series
            for (int i = 0; i < count; i++)
            {
                TradesChart.Series.ElementAt(i).Visibility = Visibility.Collapsed;
            }

            //Set the selected series visible
            foreach (MarketSelectorItem item in ((RadListPicker)sender).SelectedItems)
            {
                TradesChart.Series.ElementAt(item.Index).Visibility = Visibility.Visible;
            }
        }

        /// <summary>
        /// Pin a secondary tile linking to the current page to start
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ApplicationBarIconButton_Click(object sender, EventArgs e)
        {
            StandardTileData tileData = new StandardTileData
            {
                Title = this.pageTitle,
                BackTitle = AppResources.AppTileTitle,
                BackgroundImage = new Uri("/Images/SecondTileCurrency.png", UriKind.Relative),
                BackBackgroundImage = new Uri("/Images/SecondTileCurrencyBack.png", UriKind.Relative),
                BackContent = " ",
            };

            Uri tileUri = new Uri(this.pageURL, UriKind.Relative);

            ShellTile.Create(tileUri, tileData);
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            SystemTray.IsVisible = true;
            SystemTray.Opacity = 0;
            SystemTray.ForegroundColor = Colors.White;

            this.BuildLocalizedApplicationBar(true);

            //Set data to show
            this.setCurrentData();
            this.setTradeHistoryData();
        }

        /**
         * Builds the application Bar with translations
         */
        private void BuildLocalizedApplicationBar(bool showSettings)
        {
            ApplicationBar = new ApplicationBar();
            ApplicationBar.ForegroundColor = Colors.Black;
            ApplicationBar.BackgroundColor = ColorTools.GetColorFromHexa("#FFD8D8D8");

            ApplicationBarIconButton appBarIconReload = new ApplicationBarIconButton(new Uri("/Images/MB_0001_pin.png", UriKind.Relative));
            appBarIconReload.Text = AppResources.PinToStart;
            appBarIconReload.Click += this.ApplicationBarIconButton_Click;

            ApplicationBar.Buttons.Add(appBarIconReload);

            if (showSettings)
            {
                ApplicationBarMenuItem appBarItemSettings = new ApplicationBarMenuItem(AppResources.SettingMenuItem);
                appBarItemSettings.Click += this.ApplicationBarMenuItem_Click_1;
                ApplicationBar.MenuItems.Add(appBarItemSettings);
            }

            ApplicationBarMenuItem appBarItemAbout = new ApplicationBarMenuItem(AppResources.AboutMenuItem);
            appBarItemAbout.Click += this.ApplicationBarMenuItem_Click;
            ApplicationBar.MenuItems.Add(appBarItemAbout);
        }
    }
}